package com.vmj.instructions.references;

import com.vmj.heap.RuntimeConstantPool;
import com.vmj.heap.Method;
import com.vmj.heap.MethodRef;
import com.vmj.heap.VMClass;
import com.vmj.instructions.base.Index16Instruction;
import com.vmj.instructions.base.MethodInvokeLogic;
import com.vmj.rtda.Frame;

/**
 * Created by yangshoujun on 2017/9/2 下午3:36.
 */
public class InvokeStatic extends Index16Instruction {

    @Override
    public void execute(Frame frame) {
        RuntimeConstantPool cp = frame.getMethod().getClazz().getRuntimeConstantPool();
        MethodRef methodRef = (MethodRef) cp.getConstant(this.getIndex()).getValue();
        Method resovledMetod = methodRef.resolvedMethod();

        VMClass clazz = resovledMetod.getClazz();
        // System#loadLibrary方法暂时不清楚怎么实现，先不管
        if("loadLibrary".equals(resovledMetod.getName()) && "java/lang/System".equals(clazz.getName())) {
            return;
        }

        if(!clazz.isInitStarted()) {
            frame.revertNextPc();
            VMClass.initClass(frame.getThread(), clazz);
            return;
        }
        if(!resovledMetod.isStatic()) {
            throw new RuntimeException("java.lang.IncompatibalClassChangeError");
        }
        MethodInvokeLogic.invokeMethod(frame, resovledMetod);
    }
}
